package com.luom.fsp.service.impl;

import com.luom.fsp.mapper.OrderMapper;
import com.luom.fsp.model.vo.OrderStatsVO;
import com.luom.fsp.service.OrderStatsService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

import static com.luom.fsp.constant.RedisConstant.REDIS_DAILY_ORDERS_KEY;
import static com.luom.fsp.constant.RedisConstant.REDIS_DAILY_ORDERS_TTL;

@Service
@Slf4j
public class OrderStatsServiceImpl implements OrderStatsService {

    @Resource
    private OrderMapper orderMapper;

    @Resource
    private RedisTemplate<String, String> redisTemplate;
    
    /**
     * 获取近N日每日订单数（优先从Redis读取，缺失则查库）
     * @param days 天数
     */
    @Override
    public Map<String, String> getLastNDaysOrderCount(int days) {
        // 生成最近N天的日期列表
        List<String> dates = generateLastNDays(days);

        // 1. 批量读取Redis缓存
        Map<String, String> cachedData = getCachedData(dates);
        List<String> missingDates = findMissingDates(dates, cachedData);

        // 2. 查询缺失日期的数据
        if (!missingDates.isEmpty()) {
            Map<String, String> dbData = queryMissingDatesFromDB(missingDates);
            // 更新缓存并合并结果
            cacheAndMergeData(cachedData, dbData, missingDates);
        }

        // 3. 补全最终结果（确保数据完整）
        return buildFinalResult(dates, cachedData);
    }

    /**
     * 生成最近N天的日期字符串列表（格式：yyyy-MM-dd），不包含今天
     */
    private List<String> generateLastNDays(int days) {
        LocalDate yesterday = LocalDate.now().minusDays(1);
        return IntStream.rangeClosed(0, days - 1)
                .mapToObj(i -> yesterday.minusDays((days - 1) - i).format(DateTimeFormatter.ISO_DATE))
                .collect(Collectors.toList());
    }

    /**
     * 从Redis批量获取已缓存的数据
     */
    private Map<String, String> getCachedData(List<String> dates) {
        List<String> keys = dates.stream()
                .map(date -> REDIS_DAILY_ORDERS_KEY + date)
                .collect(Collectors.toList());

        List<String> values = redisTemplate.opsForValue().multiGet(keys);
        Map<String, String> cachedData = new LinkedHashMap<>();

        for (int i = 0; i < dates.size(); i++) {
            String date = dates.get(i);
            String value = values != null ? values.get(i) : null;
            if (value != null) {
                cachedData.put(date, value);
            }
        }
        return cachedData;
    }

    /**
     * 找出未缓存的日期
     */
    private List<String> findMissingDates(List<String> dates, Map<String, String> cachedData) {
        return dates.stream()
                .filter(date -> !cachedData.containsKey(date))
                .collect(Collectors.toList());
    }

    /**
     * 查询缺失日期的数据库数据
     */
    private Map<String, String> queryMissingDatesFromDB(List<String> missingDates) {
        List<OrderStatsVO> dbResults = orderMapper.selectDailyOrdersByDates(missingDates);
        return dbResults.stream()
                .filter(vo -> vo != null && vo.getDate() != null)
                .collect(Collectors.toMap(
                        OrderStatsVO::getDate,
                        vo -> String.valueOf(vo.getOrderCount() != null ? vo.getOrderCount() : 0),
                        (oldVal, newVal) -> oldVal,
                        LinkedHashMap::new
                ));
    }

    /**
     * 缓存新数据并合并结果
     */
    private void cacheAndMergeData(Map<String, String> cachedData, Map<String, String> dbData, List<String> missingDates) {
        dbData.forEach((date, count) -> {
            String key =  REDIS_DAILY_ORDERS_KEY + date;
            redisTemplate.opsForValue().set(key, count, REDIS_DAILY_ORDERS_TTL, TimeUnit.HOURS);
            cachedData.put(date, count);
        });

        // 处理数据库无记录的日期（设为0并缓存）
        missingDates.forEach(date -> {
            if (!dbData.containsKey(date)) {
                String key = REDIS_DAILY_ORDERS_KEY + date;
                redisTemplate.opsForValue().set(key, "0", REDIS_DAILY_ORDERS_TTL, TimeUnit.HOURS);
                cachedData.put(date, "0");
            }
        });
    }

    /**
     * 构建最终结果（确保顺序和完整性）
     */
    private Map<String, String> buildFinalResult(List<String> dates, Map<String, String> cachedData) {
        Map<String, String> finalResult = new LinkedHashMap<>();
        dates.forEach(date -> finalResult.put(date, cachedData.getOrDefault(date, "0")));
        return finalResult;
    }
}

/*

@Service
@Slf4j
public class OrderStatsServiceImpl implements OrderStatsService {

    @Resource
    private OrderMapper orderMapper;

    @Resource
    private RedisTemplate<String, String> redisTemplate;

    */
/**
     * 获取近7日每日订单数（优先从Redis读取）
     *//*

    @Override
    public Map<String, String> getLast7DaysOrderCount() {
        // 1. 尝试从Redis获取缓存
        Map<Object, Object> cachedRawData = redisTemplate.opsForHash().entries(REDIS_DAILY_ORDERS_KEY);
        if (!cachedRawData.isEmpty()) {
            return convertRedisMap(cachedRawData);
        }

        // 2. 无缓存则查询数据库
        Map<String, String> dbData = queryLast7DaysFromDB();

        // 3. 补全缺失日期并写入Redis
        Map<String, String> fullData = completeMissingDates(dbData);
        cacheToRedis(fullData);

        return fullData;
    }

    */
/**
     * 从数据库查询原始数据（直接返回String类型）
     *//*

    private Map<String, String> queryLast7DaysFromDB() {
        LocalDate endDate = LocalDate.now();
        LocalDate startDate = endDate.minusDays(6);

        List<OrderStatsVO> dbResults = orderMapper.selectDailyOrders(
                Date.from(startDate.atStartOfDay(ZoneId.systemDefault()).toInstant()),
                Date.from(endDate.plusDays(1).atStartOfDay(ZoneId.systemDefault()).toInstant())
        );

        return dbResults.stream()
                .filter(vo -> vo != null && vo.getDate() != null)
                .collect(Collectors.toMap(
                        OrderStatsVO::getDate,
                        vo -> String.valueOf(vo.getOrderCount() != null ? vo.getOrderCount() : 0), // 转为String
                        (oldVal, newVal) -> oldVal,
                        LinkedHashMap::new
                ));
    }

    */
/**
     * 补全缺失的日期（返回String类型的0）
     *//*

    private Map<String, String> completeMissingDates(Map<String, String> dbData) {
        Map<String, String> result = new LinkedHashMap<>();
        LocalDate currentDate = LocalDate.now().minusDays(6);

        for (int i = 0; i < 7; i++) {
            String dateKey = currentDate.format(DateTimeFormatter.ISO_DATE);
            result.put(dateKey, dbData.getOrDefault(dateKey, "0")); // 默认值设为"0"
            currentDate = currentDate.plusDays(1);
        }

        return result;
    }

    */
/**
     * 缓存到Redis（直接存储String类型）
     *//*

    private void cacheToRedis(Map<String, String> data) {
        try {
            redisTemplate.opsForHash().putAll(REDIS_DAILY_ORDERS_KEY, data);
            redisTemplate.expire(REDIS_DAILY_ORDERS_KEY, REDIS_DAILY_ORDERS_TTL, TimeUnit.HOURS);
            log.info("缓存成功: {}", data);
        } catch (Exception e) {
            log.error("缓存失败", e);
        }
    }

    */
/**
     * 转换Redis数据（直接返回String）
     *//*

    private Map<String, String> convertRedisMap(Map<Object, Object> redisMap) {
        return redisMap.entrySet().stream()
                .collect(Collectors.toMap(
                        e -> (String) e.getKey(),
                        e -> (String) e.getValue(), // 直接转换值
                        (oldVal, newVal) -> oldVal,
                        LinkedHashMap::new
                ));
    }
}*/
